﻿/* Copyright © Hauer Engineering 2012 */

(function ($)
{
    // Service Proxy
    // Call services using AJAX
    var serviceProxy = function (url)
    {
        this._url = url;
    };
    serviceProxy.prototype =
        {
            call: function (options)
            {
                var defaultOptions =
                    {
                        path: null,
                        httpMethod: 'POST',
                        data: null,
                        json: null,
                        timeout: 10000,
                        dataType: 'json',
                        successCallback: null,
                        errorCallback: null
                    };

                if (!options)
                    $.error('options are undefined.');

                $.extend(true, defaultOptions, options);

                var pathUrl = this._url + (defaultOptions.path == null ? '' : defaultOptions.path);

                var dataJson = null;
                if (defaultOptions.data)
                {
                    dataJson = JSON.stringify(defaultOptions.data);
                }
                else
                {
                    if (defaultOptions.json)
                    {
                        dataJson = defaultOptions.json;
                    }
                }

                // call WS using Ajax
                $.ajax({
                    type: defaultOptions.httpMethod,
                    contentType: "application/json; charset=utf-8",
                    url: pathUrl,
                    dataType: defaultOptions.dataType,
                    data: dataJson,
                    timeout: defaultOptions.timeout,
                    success: function (obj)
                    {
                        // get result
                        var result = obj;
                        // send message to user
                        if (result.messages && result.messages.length > 0)
                        {
                            for (var index in result.messages)
                            {
                                var message = result.messages[index];
                                $.heng.messaging('send', message);
                            }
                        }
                        // call success callback
                        if (result.success)
                        {
                            if (defaultOptions.successCallback)
                                defaultOptions.successCallback(result.data);
                        }
                        else
                        {
                            if (defaultOptions.errorCallback)
                                defaultOptions.errorCallback();
                        }
                    },
                    error: function (xhr)
                    {
                        var message =
                            {
                                text: 'Error occured for service method \'' + pathUrl + '\' with Status: ' + xhr.status + ' (' + xhr.statusText + ')'
                            };

                        $.heng.messaging('send', message);

                        if (defaultOptions.errorCallback)
                            defaultOptions.errorCallback();
                    }
                });
            }
        };


    // Web API Service Proxy
    // Call Web Api services using AJAX
    var apiServiceProxy = function (serviceProxy)
    {
        this._serviceProxy = serviceProxy;
    };
    apiServiceProxy.prototype =
        {
            // Calls Web Api GET method (SELECT)
            get: function(apiSpecification, serviceProxyOptions)
            {
                if (!apiSpecification || !apiSpecification.serviceProxyOptions)
                    $.error('apiServiceProxy :: apiSpecification was not defined or its serviceProxyOptions member was not defined.');

                serviceProxyOptions.httpMethod = 'GET';

                this.call(apiSpecification, serviceProxyOptions, true);
            },

            // Calls Web Api POST method (INSERT)
            post: function(apiSpecification, serviceProxyOptions)
            {
                if (!apiSpecification || !apiSpecification.serviceProxyOptions)
                    $.error('apiServiceProxy :: apiSpecification was not defined or its serviceProxyOptions member was not defined.');

                serviceProxyOptions.httpMethod = 'POST';

                this.call(apiSpecification, serviceProxyOptions, false);
            },

            // Calls Web Api PUT method (UPDATE)
            put: function (apiSpecification, serviceProxyOptions)
            {
                if (!apiSpecification || !apiSpecification.serviceProxyOptions)
                    $.error('apiServiceProxy :: apiSpecification was not defined or its serviceProxyOptions member was not defined.');

                serviceProxyOptions.httpMethod = 'PUT';

                this.call(apiSpecification, serviceProxyOptions, false);
            },

            // Calls Web Api DELETE method (DELETE)
            del: function (apiSpecification, serviceProxyOptions)
            {
                if (!apiSpecification || !apiSpecification.serviceProxyOptions)
                    $.error('apiServiceProxy :: apiSpecification was not defined or its serviceProxyOptions member was not defined.');

                serviceProxyOptions.httpMethod = 'DELETE';

                this.call(apiSpecification, serviceProxyOptions, true);
            },

            // Calls Web Api method
            call: function (apiSpecification, serviceProxyOptions, passDataAsQueryString)
            {
                if (!apiSpecification || !apiSpecification.serviceProxyOptions)
                    $.error('apiServiceProxy :: apiSpecification was not defined or its serviceProxyOptions member was not defined.');

                var defaultApiSpecification =
                    {
                    };

                $.extend(true, defaultApiSpecification, apiSpecification);

                defaultApiSpecification.serviceProxyOptions.httpMethod = 'GET';

                if (serviceProxyOptions)
                    $.extend(true, defaultApiSpecification.serviceProxyOptions, serviceProxyOptions);

                var queryString = '';

                if (passDataAsQueryString)
                {
                    if (defaultApiSpecification.serviceProxyOptions.data)
                    {
                        queryString = this.dataToQueryString(defaultApiSpecification.serviceProxyOptions.data);
                        defaultApiSpecification.serviceProxyOptions.data = null;
                    }
                    else
                    {
                        if (defaultApiSpecification.serviceProxyOptions.json)
                        {
                            queryString = this.jsonToQueryString(defaultApiSpecification.serviceProxyOptions.json);
                            defaultApiSpecification.serviceProxyOptions.json = null;
                        }
                    }
                }

                defaultApiSpecification.serviceProxyOptions.path = defaultApiSpecification.serviceProxyOptions.path + queryString;

                this._serviceProxy.call(defaultApiSpecification.serviceProxyOptions);
            },

            // Convert object to query string
            dataToQueryString: function (data)
            {
                var queryString = '';

                if (!data)
                    return queryString;

                queryString = '?';

                for (var prop in data)
                {
                    var propVal = data[prop];
                    queryString = queryString + (queryString.length > 1 ? '&' : '') + prop + '=';

                    if (!propVal)
                        continue;

                    queryString = queryString + propVal.toString();
                }

                return queryString;
            },

            // Convert JSON to query string
            jsonToQueryString: function (json)
            {
                var queryString = '';

                if (!json || json == '')
                    return queryString;

                var data = JSON.parse(json);

                queryString = this.dataToQueryString(data);

                return queryString;
            }
        };


    $.setupNamespace('heng');

    $.heng.serviceProxy = function (url)
    {
        var instance = new serviceProxy(url);
        return instance;
    }

    $.heng.apiServiceProxy = function (url)
    {
        var serviceProxyInstance = new serviceProxy(url);
        var apiServiceProxyInstance = new apiServiceProxy(serviceProxyInstance);
        return apiServiceProxyInstance;
    }
})(jQuery);